/*  ----------------------------------------------------------------------------
 *  Arello Mobile
 *  Fast 3d Engine
 *  ----------------------------------------------------------------------------
 * Except where otherwise noted, this work is licensed under
 * http://creativecommons.org/licenses/by/3.0
 */

#include "Math_lib3d.h"

namespace liba
{
namespace lib3d
{

Matrix calculate_perspective_projection_matrix( double fov, double aspect, double near_plane, double far_plane )
{
	Matrix mat = Matrix::identity();

	if( fabs( far_plane - near_plane ) < 0.000001 ) // BUG
		return mat;
	if( fabs( sin( fov/2 ) ) < 0.000001 ) // BUG
		return mat;

	double h = ( cos( fov/2 ) / sin( fov/2 ) );
	double w = aspect * h;

	mat.rc(0,0) = float(w);
	mat.rc(1,1) = float(h);
	mat.rc(2,2) = float((far_plane+near_plane)/(far_plane-near_plane));
	mat.rc(3,2) = 1;
	mat.rc(2,3) = -float(2*far_plane*near_plane/(far_plane-near_plane));
	mat.rc(3,3) = 0;

	return mat;
}

Matrix calculate_orthogonal_projection_matrix( double left, double right, double bottom, double top, double near_plane, double far_plane )
{
	Matrix mat = Matrix::identity();

/*
	mat.rc(0,0) = float( 2/(right-left));
	mat.rc(1,1) = float( 2/(top-bottom));
	mat.rc(2,2) = float(-2/( far_plane - near_plane ));
	mat.rc(0,3) = float((right+left)/(right-left));
	mat.rc(1,3) = float((top+bottom)/(top-bottom));
	mat.rc(2,3) = float(( far_plane + near_plane )/( far_plane - near_plane ));//-Q * near_plane;
*/

	mat.rc(0,0) = float( 2/(right-left));
	mat.rc(1,1) = float( 2/(top-bottom));
	mat.rc(2,2) = float( 1/( far_plane - near_plane ));
	mat.rc(0,3) = -float((right+left)/(right-left));
	mat.rc(1,3) = -float((top+bottom)/(top-bottom));
	mat.rc(2,3) = -float(( near_plane )/( far_plane - near_plane ));//-Q * near_plane;

	return mat;
}

Vector clamp( const Vector & value, const Vector & mi, const Vector & ma )
{
	Vector ret = value;
	if( ret[0] < mi[0] ) ret[0] = mi[0];
	if( ret[1] < mi[1] ) ret[1] = mi[1];
	if( ret[2] < mi[2] ) ret[2] = mi[2];
	if( ret[0] > ma[0] ) ret[0] = ma[0];
	if( ret[1] > ma[1] ) ret[1] = ma[1];
	if( ret[2] > ma[2] ) ret[2] = ma[2];
	return ret;
}

} // namespace lib3d
} // namespace liba

